﻿<%@ WebHandler Language="C#" Class="ApsLimitedCapacityHandler" %>

//Description:有限产能排产
//Copyright (c) : 通力凯顿（北京）系统集成有限公司
//Writer:Wangjh
//create Date:2022-05-13
using System;
using System.Web;
using BusinessRule.DTO;
using BusinessRule.Business;
using BusinessRule.IBusiness;
using BusinessRule.BusinessFactory;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Web.SessionState;
using System.Data;
using System.IO;
using System.Text;
using System.Linq;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using DatabaseAccess.DBUtility;
using System.Collections;

public class ApsLimitedCapacityHandler : IHttpHandler, IRequiresSessionState
{
    ApsPlanDownSendBusiness apsPlanDownSend = new ApsPlanDownSendBusiness();
    private LimitedCapacityBusiness m_LMObj = new LimitedCapacityBusiness();
    ScheduledTaskBusiness m_ScheduledTask = new ScheduledTaskBusiness();
    private uLMSCommonIBusiness m_CommonObj = uMESBusinessFactory.instance.GetuLMSCommonObject();
    string fileBasePath = System.Configuration.ConfigurationManager.AppSettings["ImportPath"].ToString();//导入临时路径
    string rbFactoryID = System.Configuration.ConfigurationManager.AppSettings["RBFactoryID"].ToString(); //热表ID
    CurrentUserInfo m_UserInfo;
    public void ProcessRequest(HttpContext context)
    {
        try
        {
            var action = context.Request["action"].ToString();
            m_UserInfo = (CurrentUserInfo)context.Session["CurrentUserInfo"];
            switch (action)
            {
                case "ImportApsSequence": //排产顺序号导入
                    ImportApsSequence(context);
                    break;
                case "ExportApsPoolDataToExcel": //排产池导出
                    ExportApsPoolDataToExcel(context);
                    break;
                case "getApsSelectContainer":
                    GetApsSelectContainer(context);
                    break;
                case "moveConToApsPool":
                    MoveConToApsPool(context);
                    break;
                case "searchData":
                    SearchData(context);
                    break;
                case "removeApsPool":
                    RemoveApsPool(context);
                    break;
                case "calcContainerApsPriority":
                    calcContainerApsPriority(context);
                    break;
                case "apsLmCalculate":
                    ApsLmCalculate(context);//有限产能排产计算
                    break;
                case "apsLmCalculateChange":
                    ApsLmCalculateChange(context);
                    break;
                case "getContainerLMAps":
                    GetContainerLMAps(context);
                    break;
                case "getStepLimitedAps"://有限产能工序级计划查看,甘特图
                    GetStepLimitedAps(context);
                    break;
                case "getStepLimitedAps2"://有限产能工序级计划查看,列表
                    GetStepLimitedAps2(context);
                    break;
                case "getWorkcenter"://获取工区信息
                    GetWorkcenter(context);
                    break;
                case "getTeam"://获取班组信息
                    GetTeam(context);
                    break;
                case "getResourceBySpec"://获取设备信息
                    GetResourceBySpec(context);
                    break;
                case "getResEmployee"://获取设备的人员信息
                    GetResEmployee(context);
                    break;
                case "getResEmployeeTime"://获取排产人员加工时间信息
                    GetResEmployeeTime(context);
                    break;
                case "apsLmCalculateExport"://排产结果导出
                    ExportApsLmCalculate(context);
                    break;
                case "apsLmCalculateImport"://排产结果调整导入  
                    apsLmCalculateImport(context);
                    break;
                case "apsLmCalculateTrial"://排产策略试算，不提交数据库  
                    ApsLmCalculateTrial(context);
                    break;
                case "getPoolList"://获取排产池列表  
                    getPoolList(context);
                    break;
                case "saveSingleSequence"://保存排产池调整的顺序号  
                    saveSingleSequence(context);
                    break;
                case "saveManualStartDate"://保存手动开始日期  
                    SaveManualStartDate(context);
                    break;
                case "isScheduledApsPool"://排产池是否正在定时计算  
                    IsScheduledApsPool(context);
                    break;
                case "apsScheduledTaskLogsExport"://错误日志导出
                    ExportApsScheduledTaskLogs(context);
                    break;
                case "DeleteApsPlanInfo"://删除排产结果信息
                    DeleteApsPlanInfo(context);
                    break;
                default:
                    break;
            }
        }
        catch (Exception e)
        {
            var result = new uMESProcessResult()
            {
                Result = false,
                Message = e.Message
            };
            context.Response.Write(JsonConvert.SerializeObject(result));
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

    /// <summary>
    /// 删除排产结果信息 add by zhangrj 2023-11-30
    /// </summary>
    /// <param name="context"></param>
    public void DeleteApsPlanInfo(HttpContext context)
    {
        uMESProcessResult result = new uMESProcessResult() { Result = true };
        string apsPlanInfoID = context.Request["aspPlanInfoID"].ToString();
        if (string.IsNullOrWhiteSpace(apsPlanInfoID))
        {
            result.Result = false; result.Message = "请点击待删除的排产数据";
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }
        string sql = string.Format(@"SELECT ap.apsplandetailid,ap.workflowstepid,ai.containerid FROM apsplaninfo ai 
                                    LEFT JOIN apsplandetail ap ON ap.apsplaninfoid = ai.apsplaninfoid
                                    WHERE ai.apsplaninfoid = '{0}'", apsPlanInfoID);
        DataTable dtAps = DatabaseHelper.Query_ReturnDatTable(sql);
        if (dtAps.Rows.Count == 0)
        {
            result.Result = false; result.Message = "排产数据不存在，请刷新页面";
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }
        //如果存在转工序已经转出，不可删除
        string errorMsg = string.Empty;
        sql = string.Format(@"SELECT to_char(wm_concat(apd.workflowstepname)) stepnames FROM apsplandetail apd 
                                    LEFT JOIN apsplaninfo ai ON ai.apsplaninfoid = apd.apsplaninfoid
                                    LEFT JOIN containercurrentinfo c ON c.containerid = ai.containerid
                                    WHERE ai.apsplaninfoid = '{0}' AND apd.specfactoryid <> c.originalfactoryid AND nvl(apd.status,'0') <> '0'", apsPlanInfoID);
        DataTable dtShipAps = DatabaseHelper.Query_ReturnDatTable(sql);
        if (dtShipAps.Rows.Count > 0 && !string.IsNullOrWhiteSpace(dtShipAps.Rows[0]["stepnames"].ToString()))
        {
            errorMsg = string.Format("转工排产工序：{0} 已排产转出确认；", dtShipAps.Rows[0]["stepnames"].ToString());
        }
        //如果存在工序已下发，不可删除
        sql = string.Format(@"SELECT to_char(wm_concat(apd.workflowstepname)) stepnames FROM apsplandetail apd 
                                    LEFT JOIN apsplaninfo ai ON ai.apsplaninfoid = apd.apsplaninfoid
                                    LEFT JOIN containercurrentinfo c ON c.containerid = ai.containerid
                                    WHERE ai.apsplaninfoid = '{0}' AND apd.specfactoryid = c.originalfactoryid AND nvl(apd.status,'0') = '1'", apsPlanInfoID);
        dtShipAps = DatabaseHelper.Query_ReturnDatTable(sql);
        if (dtShipAps.Rows.Count > 0 && !string.IsNullOrWhiteSpace(dtShipAps.Rows[0]["stepnames"].ToString()))
        {
            errorMsg += string.Format("排产工序：{0} 已下发", dtShipAps.Rows[0]["stepnames"].ToString());
        }
        if (!string.IsNullOrWhiteSpace(errorMsg))
        {
            result.Result = false; result.Message = errorMsg;
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }
        ArrayList sqlList = new ArrayList();
        ArrayList sqlList77 = new ArrayList();
        foreach (DataRow item in dtAps.Rows)
        {
            //删除排产人员时间明细
            sqlList.Add(string.Format(@"DELETE FROM apsplandetailemptime apt WHERE apt.apsplandetailempid IN (
                                    SELECT ape.apsplandetailempid FROM apsplandetailemp ape
                                    WHERE ape.apsplandetailid = '{0}')", item["apsplandetailid"].ToString()));
            //删除排产人员
            sqlList.Add(string.Format(@"DELETE FROM apsplandetailemp ape WHERE ape.apsplandetailid = '{0}'", item["apsplandetailid"].ToString()));
            //删除排产发送看板中间表信息
            sqlList.Add(string.Format(@"DELETE containerstepplan csp WHERE csp.containerid = '{0}' AND csp.workflowstepid = '{1}'", item["containerid"].ToString(), item["workflowstepid"].ToString()));
            //删除77数据库的排产看板数据
            sqlList77.Add(string.Format(@"DELETE r_containerstepplanboard r WHERE r.containerid = '{0}' AND r.workflowstepid = '{1}'", item["containerid"].ToString(), item["workflowstepid"].ToString()));
        }
        //删除排产明细
        sqlList.Add(string.Format(@"DELETE FROM apsplandetail apd WHERE apd.apsplaninfoid = '{0}'", apsPlanInfoID));
        //删除排产信息
        sqlList.Add(string.Format(@"DELETE FROM apsplaninfo ai WHERE ai.apsplaninfoid = '{0}'", apsPlanInfoID));
        DatabaseHelper.ExecuteSqlTran(sqlList);
        DatabaseHelper.ExecuteSqlTranBy77(sqlList77);
        result.Message = "删除成功";
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    /// <summary>
    /// 导入排产顺序号 add by zhangrj 2023-11-20
    /// </summary>
    /// <param name="context"></param>
    public void ImportApsSequence(HttpContext context)
    {
        string fpath = string.Empty;
        try
        {
            var files = context.Request.Files;
            if (files.Count == 0)
            {
                context.Response.Write(JsonConvert.SerializeObject(new uMESProcessResult() { Message = "未上传文件！", Result = false }));
                return;
            }
            var file = files.Count > 1 ? files[files.Count - 1] : files[0];
            string IsXls = Path.GetExtension(file.FileName);
            string fileName = Path.GetFileNameWithoutExtension(file.FileName) + DateTime.Now.ToString("yyyyMMddHHmmssffff") + IsXls;
            fpath = context.Server.MapPath(fileBasePath + fileName);
            file.SaveAs(fpath);//保存文件，处理完成后删除

            IWorkbook Workbook = uLMS_CommonFunction.GetWorkbookObj(fpath);
            if (Workbook == null)
            {
                DeleteFile(fpath);
                context.Response.Write(JsonConvert.SerializeObject(new uMESProcessResult() { Message = "解析文件出错", Result = false }));
                return;
            }
            DeleteFile(fpath);
            DataTable dtImport = uLMS_CommonFunction.ExcelImportToDataTable(Workbook);
            uMESProcessResult result = new uMESProcessResult() { Result = true };
            if (dtImport.Rows.Count == 0)
            {
                result.Result = false; result.Message = "解析内容出错";
                goto L1;
            }
            if (!dtImport.Columns.Contains("批次") || !dtImport.Columns.Contains("排产顺序号"))
            {
                result.Result = false; result.Message = "导入模板表头有误，缺少批次或者排产顺序号";
                goto L1;
            }
            if (dtImport.Select("排产顺序号 IS NULL OR 排产顺序号 = ''").Length > 0)
            {
                result.Result = false; result.Message = "导入的排产顺序号存在为空的情况，请检查文件";
                goto L1;
            }
            if (dtImport.AsDataView().ToTable(true, "排产顺序号").Rows.Count != dtImport.Rows.Count)
            {
                result.Result = false; result.Message = "导入排产顺序号存在相同的情况，请检查文件";
                goto L1;
            }
            dtImport.Columns.Add("IsResult");
            dtImport.Columns.Add("ResultMessage");
            string containerNames = string.Empty;//批次名合集
            string sql = string.Empty;//sql
            dtImport.AsEnumerable().ToList().ForEach(p => { containerNames += string.Format("'{0}',", p["批次"].ToString()); });
            containerNames = containerNames.TrimEnd(',');
            sql = string.Format(@"SELECT distinct cci.apspoolid 
                                  FROM containercurrentinfo cci WHERE cci.containername IN ({0})", containerNames);
            DataTable dtContainer = DatabaseHelper.Query_ReturnDatTable(sql);//查询所有导入的批次是否在同一个排产池中
            if (dtContainer.Rows.Count != 1)
            {
                result.Result = false; result.Message = "导入批次必须在同一个排产池里";
                goto L1;
            }
            string apsPoolID = dtContainer.Rows[0]["apspoolid"].ToString();//排产池
            //if (string.IsNullOrWhiteSpace(apsPoolID))
            //{
            //    result.Result = false; result.Message = "导入批次未查到排产池";
            //    goto L1;
            //}
            int seq = 0;
            foreach (DataRow item in dtImport.Rows)
            {
                /*验证顺序号是否为整数*/
                if (!int.TryParse(item["排产顺序号"].ToString(), out seq))
                {
                    item["IsResult"] = false;
                    item["ResultMessage"] = "顺序号格式不正确";
                    continue;
                }
                /*查询是否存在批次*/
                sql = string.Format("SELECT 1 FROM containercurrentinfo cci WHERE cci.containername = '{0}'", item["批次"].ToString());
                if (DatabaseHelper.GetSingle(sql) == null)
                {
                    item["IsResult"] = false;
                    item["ResultMessage"] = "不存在该批次";
                    continue;
                }
                /*查询要修改的顺序号是否已存在*/
                sql = string.Format(@"SELECT cci.containername FROM containercurrentinfo cci 
                                      WHERE cci.apspoolid = '{0}' AND cci.containername != '{1}' AND cci.apssequence = '{2}'", apsPoolID, item["批次"].ToString(), item["排产顺序号"].ToString());
                DataTable dtRes = DatabaseHelper.Query_ReturnDatTable(sql);
                if (dtRes.Rows.Count > 0 && dtImport.Select(string.Format("批次='{0}'", dtRes.Rows[0]["containername"].ToString())).Length == 0)
                {
                    item["IsResult"] = false;
                    item["ResultMessage"] = "已存在该顺序号";
                    continue;
                }
                /*更新数据*/
                sql = string.Format("UPDATE containercurrentinfo cci SET cci.apssequence = '{0}' WHERE cci.containername = '{1}'", item["排产顺序号"].ToString(), item["批次"].ToString());
                DatabaseHelper.ExecuteSql(sql);
                item["IsResult"] = true;
                item["ResultMessage"] = "更改成功";
            }
            result.DBTable = dtImport;
        L1: context.Response.Write(JsonConvert.SerializeObject(result));
        }
        catch (Exception ex)
        {
            DeleteFile(fpath);//报错，则删除上传的文件
            context.Response.Write(JsonConvert.SerializeObject(new uMESProcessResult() { Message = ex.Message, Result = false }));
        }
    }
    /// <summary>
    /// 排产池导出 add by zhangrj 2023-10-10
    /// </summary>
    /// <param name="context"></param>
    public void ExportApsPoolDataToExcel(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        uMESProcessResult result = new uMESProcessResult();
        result.Result = false;
        Dictionary<string, string> para = SetPara(context);
        result = m_LMObj.GetApsPoolContainerInfo(para);
        DataTable dtExport = result.DBTable.AsDataView().ToTable(false, "MFGORDERNAME", "CONTAINERNAME", "PRODUCTDESC",
            "QTY", "ISPREPARE", "STEPDURATION", "CRITICALVALUE", "APSSEQUENCE", "WORKFLOWINFO", "WORKFLOWSTEPNAME", "CONTAINERTYPENAME", "REALSTARTDATE");//只保留需导出的列
        dtExport.Columns["MFGORDERNAME"].ColumnName = "订单号";
        dtExport.Columns["CONTAINERNAME"].ColumnName = "批次";
        dtExport.Columns["PRODUCTDESC"].ColumnName = "零件名称";
        dtExport.Columns["QTY"].ColumnName = "在制数";
        dtExport.Columns["ISPREPARE"].ColumnName = "齐套";
        dtExport.Columns["STEPDURATION"].ColumnName = "批次总期量";
        dtExport.Columns["CRITICALVALUE"].ColumnName = "批次临界比";
        dtExport.Columns["APSSEQUENCE"].ColumnName = "排产顺序号";
        dtExport.Columns["WORKFLOWINFO"].ColumnName = "工艺信息";
        dtExport.Columns["WORKFLOWSTEPNAME"].ColumnName = "当前工序";
        dtExport.Columns["CONTAINERTYPENAME"].ColumnName = "流水卡类型";
        dtExport.Columns["REALSTARTDATE"].ColumnName = "实际开始日期";
        byte[] bytes = uLMS_CommonFunction.DataTableExportToExcel(dtExport, "排产池批次信息");
        context.Response.Clear();
        context.Response.Buffer = true;
        context.Response.ClearHeaders();
        context.Response.ClearContent();
        context.Response.ContentType = "application/vnd.ms-excel";
        context.Response.AddHeader("fileDownload", "1");
        context.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}{1}.xls", context.Server.UrlEncode("排产池批次信息"), DateTime.Now.ToString("yyyyMMddHHmmssffff")));
        context.Response.AddHeader("Content-Length", bytes.Length.ToString());
        context.Response.AddHeader("Content-Type", "UTF-8");
        context.Response.Charset = "UTF-8";
        context.Response.ContentEncoding = System.Text.Encoding.UTF8;
        context.Response.BinaryWrite(bytes);
        context.Response.Flush();
        context.Response.Close();
    }

    /// <summary>
    /// 排产池是否正在定时计算,true:正在计算，false:没有计算
    /// </summary>
    /// <param name="context"></param>
    public void IsScheduledApsPool(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        uMESProcessResult result = new uMESProcessResult();
        result.Result = false;

        var apsPoolId = context.Request["apspoolid"].ToString();
        var temp = m_ScheduledTask.GetScheduledTaskByAttr("排产池", apsPoolId);
        if (temp.Rows.Count > 0 && temp.Rows[0]["status"].ToString() == "2")//执行中
        {
            result.Result = true; result.Message = "对应定时任务：" + temp.Rows[0]["taskname"].ToString() + " 正在执行中";
            goto re;
        }

        result.Message = "";
    re:
        context.Response.Write(JsonConvert.SerializeObject(result));
    }
    /// <summary>
    /// 保存手动开始日期
    /// </summary>
    /// <param name="context"></param>
    public void SaveManualStartDate(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        uMESProcessResult result = new uMESProcessResult();
        result.Result = false;

        DataTable conDt = new DataTable();
        if (!string.IsNullOrWhiteSpace(context.Request.Form["containers"].ToString()))
        {
            conDt = JsonConvert.DeserializeObject<DataTable>(context.Request.Form["containers"].ToString());
        }
        else
        {
            result.Message = "无效参数";
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }

        foreach (DataRow row in conDt.Rows)
        {
            var exuteEntity = new ExcuteEntity("containercurrentinfo", ExcuteEntity.ExcuteTypeEnum.update);
            var excuteFileds = new List<FieldEntity>() { new FieldEntity("ExpectMaterialDate", string.IsNullOrWhiteSpace(row["REALSTARTDATE2"].ToString()) == true ? (DateTime?)null : DateTime.Parse(row["REALSTARTDATE2"].ToString()), FieldEntity.FieldTypeEnum.DateTime) };
            exuteEntity.ExcuteFileds = excuteFileds;
            exuteEntity.WhereFileds = new List<FieldEntity>() { new FieldEntity("containerid", row["Containerid"].ToString(), FieldEntity.FieldTypeEnum.Str) };

            DatabaseHelper.ExecuteDataByEntity(exuteEntity);
        }

        result.Result = true; result.Message = "保存成功";
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    /// <summary>
    /// 保存顺序号
    /// add:yuxj
    /// </summary>
    /// <param name="context"></param>
    public void saveSingleSequence(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        uMESProcessResult result = new uMESProcessResult();
        result.Result = false;

        Dictionary<string, string> para = new Dictionary<string, string>();
        para["containerID"] = context.Request["containerID"].ToString();
        para["Seq"] = context.Request["seq"].ToString();
        para["poolid"] = context.Request["poolid"].ToString();

        if (!m_LMObj.checkSingleSequence(para))
        {
            result.Result = false;
            result.Message = "顺序号已经存在！";
        }
        else
        {
            int i = m_LMObj.saveSingleSequence(para);
            if (i > 0)
            {
                result.Result = true;
                result.Message = "调整成功！";
            }
            else
            {
                result.Result = false;
                result.Message = "调整不成功！";
            }
        }

        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    /// <summary>
    /// 获取排产池列表
    /// add:yuxj
    /// </summary>
    /// <param name="context"></param>
    public void getPoolList(HttpContext context)
    {
        Dictionary<string, string> para = new Dictionary<string, string>();
        para["FactoryID"] = context.Request["factoryId"].ToString();
        if (m_UserInfo != null)
        {
            para["EmployeeID"] = m_UserInfo.EmployeeID.ToString();
        }
        DataTable dt = m_LMObj.GetPoolList(para);
        DataTable result = new DataTable();
        result.Columns.Add("APSPOOLID");
        result.Columns.Add("APSPOOLNAME");

        DataRow reRow = result.NewRow();
        foreach (DataRow row in dt.Rows)
        {
            reRow = result.NewRow();
            reRow["APSPOOLID"] = row["APSPOOLID"];
            reRow["APSPOOLNAME"] = row["APSPOOLNAME"];

            result.Rows.Add(reRow);
        }
        result.AcceptChanges();
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    /// <summary>
    /// 有限产能排产
    /// </summary>
    /// <param name="context"></param>
    public void ApsLmCalculateTrial(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        uMESProcessResult result = new uMESProcessResult();
        result.Result = false;

        Dictionary<string, string> para = new Dictionary<string, string>();
        para["EmployeeID"] = m_UserInfo.EmployeeID.ToString();

        DataTable conDt = new DataTable();
        if (!string.IsNullOrWhiteSpace(context.Request.Form["containers"].ToString()))
        {
            conDt = JsonConvert.DeserializeObject<DataTable>(context.Request.Form["containers"].ToString());
        }
        else
        {
            result.Message = "无效参数";
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }
        if (!string.IsNullOrWhiteSpace(context.Request["noIncludeMC"].ToString()))
        {//不考虑日历            
            para.Add("NoIncludeMC", context.Request["noIncludeMC"].ToString());
        }
        if (!string.IsNullOrWhiteSpace(context.Request["noIncludeUK"].ToString()))
        {//不考虑保养            
            para.Add("NoIncludeUK", context.Request["noIncludeUK"].ToString());
        }
        if (!string.IsNullOrWhiteSpace(context.Request["noIncludeOP"].ToString()))
        {//不考虑占用            
            para.Add("NoIncludeOP", context.Request["noIncludeOP"].ToString());
        }
        if (!string.IsNullOrWhiteSpace(context.Request["noIncludeSF"].ToString()))
        {//不考虑班次            
            para.Add("NoIncludeSF", context.Request["noIncludeSF"].ToString());
        }

        string apsType = conDt.Rows[0]["apstype"].ToString();

        DataTable faConDt = new DataTable();
        if (conDt.Select("ISSUBCON is null").Length > 0)
        {
            faConDt = conDt.Select("ISSUBCON is null").CopyToDataTable();//主卡            
        }
        DataTable sonConDt = new DataTable();
        if (conDt.Select("ISSUBCON='1'").Length > 0)
        {
            sonConDt = conDt.Select("ISSUBCON='1'").CopyToDataTable();//子卡
        }
        //排产主卡
        if (apsType == "1")//有限，正排
        {
            result = m_LMObj.LMPositiveCalculateTrial(faConDt, para);
        }
        else if (apsType == "2")//有限，倒排
        {
            result = m_LMObj.LMReverseCalculateTrial(faConDt, para);
        }
        else if (apsType == "3")//有限，瓶颈排
        {
            result = m_LMObj.LMBottleneckCalculateTrial(faConDt, para);
        }
        //排产子卡
        if (result.Result && sonConDt.Rows.Count > 0)
        {
            sonConDt = m_LMObj.GetSonContainerStartEndDate(sonConDt, apsType);
            if (sonConDt.Select("STARTTIME is null").Length > 0)
            {
                result.Result = false;
                result.Message = "未找到主卡的子工序的排产信息";
            }
            else
            {
                if (apsType == "1")//有限，正排
                {
                    result = m_LMObj.LMPositiveCalculateTrial(sonConDt, para);
                }
                else if (apsType == "2")//有限，倒排
                {
                    result = m_LMObj.LMReverseCalculateTrial(sonConDt, para);
                }
                else if (apsType == "3")//有限，瓶颈排
                {
                    result = m_LMObj.LMBottleneckCalculateTrial(sonConDt, para);
                }
            }

        }

        if (!result.Result)
        {
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }

        DataTable dt = new DataTable();
        dt.Columns.Add("STARTTIME"); dt.Columns.Add("ENDTIME");
        var row = dt.NewRow();

        row["STARTTIME"] = result.DBTable.Rows[0]["simulateStart"];
        row["ENDTIME"] = result.DBTable.Rows[result.DBTable.Rows.Count - 1]["simulateEnd"];
        dt.Rows.Add(row);

        result.DBTable = dt;
        result.Result = true;
        context.Response.Write(JsonConvert.SerializeObject(result));
    }


    /// <summary>
    /// 导出排产数据
    /// </summary>
    /// <param name="context"></param>
    public void ExportApsLmCalculate(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        uMESProcessResult result = new uMESProcessResult();
        result.Result = false;

        DataTable conDt = new DataTable();
        if (!string.IsNullOrWhiteSpace(context.Request["containers"].ToString()))
        {
            conDt = JsonConvert.DeserializeObject<DataTable>(context.Request["containers"].ToString());
        }
        else
        {
            result.Message = "无效参数";
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }
        var apsplandetailids = string.Empty;
        if (!string.IsNullOrWhiteSpace(context.Request["ids"].ToString()))
        {
            apsplandetailids = context.Request["ids"].ToString();
        }

        DataTable dt = m_LMObj.GetContainerLMApsExport(conDt, apsplandetailids);

        dt.Columns["apsplandetailid"].ColumnName = "apsplandetailid(勿改)";
        dt.Columns["apstypename"].ColumnName = "策略(勿改)";
        dt.Columns["realcontainerno"].ColumnName = "批次号(勿改)";
        dt.Columns["productname"].ColumnName = "件号(勿改)";
        dt.Columns["workflowname"].ColumnName = "工艺规程(勿改)";
        dt.Columns["workflowrevision"].ColumnName = "工艺版本(勿改)";
        dt.Columns["workflowstepname"].ColumnName = "工序(勿改)";
        dt.Columns["workcentername"].ColumnName = "工区(勿改)";
        dt.Columns["teamname"].ColumnName = "班组(勿改)";
        dt.Columns["resourcedesc"].ColumnName = "设备名称(勿改)";
        dt.Columns["resourcename"].ColumnName = "设备编码";
        dt.Columns["apsempname"].ColumnName = "人员(勿改)";
        dt.Columns["starttime"].ColumnName = "计划开始时间";
        dt.Columns["endtime"].ColumnName = "计划结束时间";

        var ms = uLMS_CommonFunction.DataTableExportToExcel(dt, "正式排-排产结果");


        var Response = HttpContext.Current.Response;
        Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}{1}.xls", HttpContext.Current.Server.UrlEncode("排产结果"), DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss")));
        Response.AddHeader("fileDownload", "1");
        Response.AddHeader("Set-Cookie", "fileDownload=true;path=/");
        Response.ContentEncoding = System.Text.Encoding.GetEncoding("UTF-8");
        Response.ContentType = "application/ms-excel;charset=UTF-8";
        Response.BinaryWrite(ms);

        Response.Flush();
        Response.End();
        Response.Close();

        context.Response.Write(JsonConvert.SerializeObject(Response));
    }
    /// <summary>
    /// 排产结果调整导入
    /// </summary>
    /// <param name="context"></param>
    private void apsLmCalculateImport(HttpContext context)
    {
        string fpath = string.Empty;
        try
        {
            var files = context.Request.Files;
            if (files.Count == 0)
            {
                context.Response.Write(JsonConvert.SerializeObject(new uMESProcessResult() { Message = "未上传文件！", Result = false }));
                return;
            }

            if (!System.IO.Directory.Exists(context.Server.MapPath(fileBasePath)))
            {
                System.IO.Directory.CreateDirectory(context.Server.MapPath(fileBasePath));
            }
            var file = files.Count > 1 ? files[files.Count - 1] : files[0];
            string IsXls = System.IO.Path.GetExtension(file.FileName);
            string fileName = System.IO.Path.GetFileNameWithoutExtension(file.FileName) + DateTime.Now.ToString("yyyyMMddHHmmssffff") + IsXls;
            fpath = context.Server.MapPath(fileBasePath + fileName);
            file.SaveAs(fpath);//保存文件，处理完成后删除
            IWorkbook Workbook = uLMS_CommonFunction.GetWorkbookObj(fpath);
            if (Workbook == null)
            {
                DeleteFile(fpath);
                context.Response.Write(JsonConvert.SerializeObject(new uMESProcessResult() { Message = "解析出错", Result = false }));
                return;
            }
            DeleteFile(fpath);
            ISheet sheet = Workbook.GetSheetAt(0);

            var dt = uLMS_CommonFunction.ExcelImportToDataTable(Workbook, 1);

            uMESProcessResult result;
            result = GetapsLmCalculateData(dt);
            context.Response.Write(JsonConvert.SerializeObject(result));
        }
        catch (Exception ex)
        {
            DeleteFile(fpath);//报错，则删除上传的文件
            context.Response.Write(JsonConvert.SerializeObject(new uMESProcessResult() { Message = ex.Message, Result = false }));
        }
    }
    /// <summary>
    /// 处理Excle单元格数据
    /// rewrite:Wangjh 20230321
    /// </summary>
    /// <param name="sheet"></param>
    /// <param name="IsXls"></param>
    /// <returns></returns>
    private uMESProcessResult GetapsLmCalculateData(DataTable importDt)
    {
        uMESProcessResult result = new uMESProcessResult();
        result.Result = false;

        //解析的Excel列验证
        if (!importDt.Columns.Contains("设备编码") || !importDt.Columns.Contains("计划开始时间")
            || !importDt.Columns.Contains("计划结束时间") || !importDt.Columns.Contains("apsplandetailid(勿改)")
            || !importDt.Columns.Contains("件号(勿改)") || !importDt.Columns.Contains("工序(勿改)"))
        {
            result.Message = "导入的数据列名错误";
            return result;
        }
        string apsPlanDetailIDs = string.Empty;
        DataTable Errordt = new DataTable();//格式错误行数据集
        Errordt.Columns.Add("apsplandetailid");
        Errordt.Columns.Add("workflowstepname");
        Errordt.Columns.Add("productname");
        Errordt.Columns.Add("Error");
        DataTable apsLmdt = new DataTable();//筛选无误数据集
        apsLmdt.Columns.Add("apsplandetailid");
        apsLmdt.Columns.Add("resourceid");
        apsLmdt.Columns.Add("starttime");
        apsLmdt.Columns.Add("endtime");
        var resSelectSQL = "SELECT r.resourceid FROM RESOURCEDEF r WHERE r.RESOURCENAME ='{0}'";
        string sql = string.Empty;
        for (int i = 0; i < importDt.Rows.Count; i++)
        {
            DataRow row = importDt.Rows[i];
            DataRow Rrow = Errordt.NewRow();//错误行
            DataRow SRow = apsLmdt.NewRow();//正确行
            var startTime = new DateTime();
            var endTime = new DateTime();
            object resourceid = "";
            if (!DateTime.TryParse(row["计划开始时间"].ToString(), out startTime))
            {
                Rrow["Error"] = "计划开始时间格式错误,";
            }
            if (!DateTime.TryParse(row["计划结束时间"].ToString(), out endTime))
            {
                Rrow["Error"] = "计划结束时间格式错误,";
            }
            if (endTime < startTime)
            {
                Rrow["Error"] = "计划开始时间不能小于计划结束时间,";
            }
            if (!string.IsNullOrWhiteSpace(row["设备编码"].ToString()))
            {
                resourceid = DatabaseHelper.GetSingle(string.Format(resSelectSQL, row["设备编码"].ToString()));
                if (resourceid == null)
                {
                    Rrow["Error"] = "设备编码未找到,";
                }

            }
            /***增加转工验证**/
            sql = string.Format(@"SELECT ap.containerid,s.specno,ws.workflowstepname,ws.workflowstepid,ap.specfactoryid FROM apsplandetail ap
                                LEFT JOIN workflowstep ws ON ws.workflowstepid = ap.workflowstepid
                                LEFT JOIN specbase sb ON sb.specbaseid = ws.specbaseid
                                LEFT JOIN spec s ON s.specid = NVL(sb.revofrcdid,ws.specid)
                                WHERE ap.apsplandetailid = '{0}'", row["apsplandetailid(勿改)"].ToString());
            DataTable dtSpec = DatabaseHelper.Query_ReturnDatTable(sql);
            sql = string.Format(@" SELECT 1 FROM containershiprecord csr 
                                LEFT JOIN containershiprecordstep csdd ON csdd.containershiprecordid = csr.containershiprecordid
                                LEFT JOIN workflowstep ws ON ws.workflowstepid = csdd.workflowstepid
                                LEFT JOIN specbase sb ON sb.specbaseid = ws.specbaseid
                                LEFT JOIN spec s ON s.specid = NVL(sb.revofrcdid,ws.specid)
                                WHERE csr.containerid = '{0}' AND csr.isuse = 0 AND s.specno = '{1}' AND csr.senddate IS NOT NULL", dtSpec.Rows[0]["containerid"].ToString(), dtSpec.Rows[0]["specno"].ToString());
            if (DatabaseHelper.GetSingle(sql) != null)
            {
                Rrow["Error"] = string.Format("工序：{0}已转工转出，无法修改", dtSpec.Rows[0]["workflowstepname"].ToString());
            }
            if (dtSpec.Rows[0]["specfactoryid"].ToString() == rbFactoryID && startTime < DateTime.Now.AddDays(3))
            {
                Rrow["Error"] = "开始日期必须为三天之后";
            }

            if (!Rrow.IsNull("Error"))
            {
                Rrow["apsplandetailid"] = row["apsplandetailid(勿改)"].ToString();
                Rrow["productname"] = row["件号(勿改)"].ToString();
                Rrow["workflowstepname"] = row["工序(勿改)"].ToString();
                Rrow["Error"] = "第" + (i + 1) + "条数据" + Rrow["Error"].ToString().TrimEnd(',');
                Errordt.Rows.Add(Rrow);
            }
            else
            {
                SRow["apsplandetailid"] = row["apsplandetailid(勿改)"].ToString();
                SRow["resourceid"] = resourceid.ToString();
                SRow["starttime"] = startTime;
                SRow["endtime"] = endTime;
                apsLmdt.Rows.Add(SRow);
                apsPlanDetailIDs += string.Format("'{0}',", row["apsplandetailid(勿改)"].ToString());
            }
        }

        if (apsLmdt.Rows.Count > 0)
        {
            result.Result = m_LMObj.UpdateContainerLMApsImport(apsLmdt);
            result.Message = result.Result ? "导入成功" + apsLmdt.Rows.Count + "条数据" + (Errordt.Rows.Count > 0 ? ";导入失败" + Errordt.Rows.Count + "条数据" : "") : "导入失败";
            apsPlanDetailIDs = apsPlanDetailIDs.TrimEnd(',');
            apsPlanDownSend.SendHandApsDatasByShipReceive(apsPlanDetailIDs); //下发到手动看板，更新看板中间表
        }

        result.ReturnData = Errordt;
        return result;
    }

    /// <summary>
    /// 删除文件
    /// </summary>
    /// <param name="fpath">文件地址</param>
    private void DeleteFile(string fpath)
    {
        if (File.Exists(fpath))
        {
            new FileInfo(fpath).Attributes = FileAttributes.Normal;
            File.Delete(fpath);
        }
    }


    /// <summary>
    /// 获取排产人员的加工时间
    /// </summary>
    /// <param name="context"></param>
    public void GetResEmployeeTime(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        uMESProcessResult result = new uMESProcessResult();
        result.Result = false;

        Dictionary<string, string> para = new Dictionary<string, string>();
        if (context.Request["apsplanDetailId"] != null && !string.IsNullOrWhiteSpace(context.Request["apsplanDetailId"].ToString()))
        {
            para.Add("ApsplanDetailID", context.Request["apsplanDetailId"].ToString());
        }

        if (para.Keys.Count == 0)
        {
            result.Message = "无参数";
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }

        var dt = m_LMObj.GetApsEmpTime(para);

        result.DBTable = dt;
        result.Result = true;
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    /// <summary>
    /// 有限产能排产
    /// </summary>
    /// <param name="context"></param>
    public void ApsLmCalculateChange(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        uMESProcessResult result = new uMESProcessResult();
        result.Result = false;

        Dictionary<string, string> para = new Dictionary<string, string>();
        para["EmployeeID"] = m_UserInfo.EmployeeID.ToString();
        para["ApsType"] = context.Request["apstype"].ToString();
        para["StartTime"] = context.Request["startTime"].ToString();
        para["EndTime"] = context.Request["endTime"].ToString();
        para["WorkcenterID"] = context.Request["workcenterId"].ToString();
        para["TeamID"] = context.Request["TeamId"].ToString();
        para["EmployeeIds"] = context.Request["employeeIds"].ToString();
        para["ResourceID"] = context.Request["resourceId"].ToString();
        para["ApsplanDetailID"] = context.Request["apsplanDetailId"].ToString();
        para["Sequence"] = context.Request["sequence"].ToString();
        DataTable conDt = new DataTable();
        if (!string.IsNullOrWhiteSpace(context.Request.Form["containers"].ToString()))
        {
            conDt = JsonConvert.DeserializeObject<DataTable>(context.Request.Form["containers"].ToString());
        }
        else
        {
            result.Message = "无效参数";
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }

        if (DateTime.Parse(para["StartTime"]) > DateTime.Parse(para["EndTime"]))
        {
            result.Message = "排产开始日期大于结束日期";
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }

        string sql = string.Empty;
        sql = string.Format(@"SELECT ap.containerid,s.specno,ws.workflowstepname,ap.specfactoryid,NVL(ap.status,0) status FROM apsplandetail ap
                                LEFT JOIN workflowstep ws ON ws.workflowstepid = ap.workflowstepid
                                LEFT JOIN specbase sb ON sb.specbaseid = ws.specbaseid
                                LEFT JOIN spec s ON s.specid = NVL(sb.revofrcdid,ws.specid)
                                WHERE ap.apsplandetailid = '{0}'", para["ApsplanDetailID"]);
        DataTable dtSpec = DatabaseHelper.Query_ReturnDatTable(sql);
        if (dtSpec.Rows[0]["status"].ToString() != "0")
        {
            result.Message = string.Format("工序：{0}已转工转出确认或已下发，无法修改", dtSpec.Rows[0]["workflowstepname"].ToString());
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }
        sql = string.Format(@" SELECT 1 FROM containershiprecord csr 
                                LEFT JOIN containershiprecordstep csdd ON csdd.containershiprecordid = csr.containershiprecordid
                                LEFT JOIN workflowstep ws ON ws.workflowstepid = csdd.workflowstepid
                                LEFT JOIN specbase sb ON sb.specbaseid = ws.specbaseid
                                LEFT JOIN spec s ON s.specid = NVL(sb.revofrcdid,ws.specid)
                                WHERE csr.containerid = '{0}' AND csr.isuse = 0 AND s.specno = '{1}' AND csr.senddate IS NOT NULL", dtSpec.Rows[0]["containerid"].ToString(), dtSpec.Rows[0]["specno"].ToString());
        if (DatabaseHelper.GetSingle(sql) != null)
        {
            result.Message = string.Format("工序：{0}已转工转出，无法修改", dtSpec.Rows[0]["workflowstepname"].ToString());
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }
        if (dtSpec.Rows[0]["specfactoryid"].ToString() == rbFactoryID && DateTime.Parse(para["StartTime"]) < DateTime.Now.AddDays(3))
        {
            result.Message = "开始日期必须为三天之后";
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }

        result = m_LMObj.LMAPSChange(conDt, para);

        if (!result.Result)
        {
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }

        result.Result = true;
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    /// <summary>
    /// 获取设备的人员
    /// </summary>
    /// <param name="context"></param>
    public void GetResEmployee(HttpContext context)
    {
        if (context.Request["resourceId"] != null && string.IsNullOrWhiteSpace(context.Request["resourceId"].ToString()))
        {
            return;
        }
        var dt = m_LMObj.Aps_GetResEmpDt("'" + context.Request["resourceId"].ToString() + "'");
        context.Response.Write(JsonConvert.SerializeObject(dt));
    }
    /// <summary>
    /// 获取设备
    /// </summary>
    /// <param name="context"></param>
    public void GetResourceBySpec(HttpContext context)
    {
        if (context.Request["specId"] != null && string.IsNullOrWhiteSpace(context.Request["specId"].ToString()))
        {
            return;
        }
        var specId = "";
        foreach (string id in context.Request["specId"].ToString().Split(','))
        {
            specId += "'" + id + "',";
        }
        specId = specId.TrimEnd(',');
        var dt = m_LMObj.Aps_GetSpecResourceDt(specId);

        context.Response.Write(JsonConvert.SerializeObject(dt));
    }
    /// <summary>
    /// 获取班组
    /// </summary>
    /// <param name="context"></param>
    public void GetTeam(HttpContext context)
    {
        if (string.IsNullOrWhiteSpace(context.Request["workcenterId"].ToString()))
        {
            return;
        }
        var dt = m_CommonObj.GetTeam(context.Request["workcenterId"].ToString());
        context.Response.Write(JsonConvert.SerializeObject(dt));
    }
    /// <summary>
    /// 获取工区信息
    /// </summary>
    /// <param name="context"></param>
    public void GetWorkcenter(HttpContext context)
    {
        var wcdt = m_CommonObj.GetWorkCenterByFacoryID(m_UserInfo.FactoryID, false);
        var drs = wcdt.Select(" notes is null or notes <>'已注销' ");
        if (drs.Length > 0)
        {
            wcdt = drs.CopyToDataTable();
        }
        context.Response.Write(JsonConvert.SerializeObject(wcdt));
    }
    /// <summary>
    /// 获取工序的排产计划,列表展示用
    /// </summary>
    /// <param name="context"></param>
    public void GetStepLimitedAps2(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        uMESProcessResult result = new uMESProcessResult();
        result.Result = false;

        Dictionary<string, string> para = new Dictionary<string, string>();
        if (context.Request["apsPlanInfoID"] != null && !string.IsNullOrWhiteSpace(context.Request["apsPlanInfoID"].ToString()))
        {
            para.Add("ApsPlanInfoID", context.Request["apsPlanInfoID"].ToString());
        }

        if (context.Request["workflowStepId"] != null && !string.IsNullOrWhiteSpace(context.Request["workflowStepId"].ToString()))
        {
            para.Add("WorkflowStepID", context.Request["workflowStepId"].ToString());
        }

        if (para.Keys.Count == 0)
        {
            result.Message = "参数无效";
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }

        DataTable dt = m_LMObj.GetStepLMAps2(para);

        if (dt.Rows.Count == 0)
        {
            result.Message = "无数据";
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }

        result.DBTable = dt;
        result.Result = true;
        context.Response.Write(JsonConvert.SerializeObject(result));
    }
    /// <summary>
    /// 获取工序的排产计划,甘特图用
    /// </summary>
    /// <param name="context"></param>
    public void GetStepLimitedAps(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        uMESProcessResult result = new uMESProcessResult();
        result.Result = false;

        Dictionary<string, string> para = new Dictionary<string, string>();
        para.Add("ApsPlanInfoIDs", "");
        if (!string.IsNullOrWhiteSpace(context.Request["param"].ToString()))
        {
            DataTable param = JsonConvert.DeserializeObject<DataTable>(context.Request["param"].ToString());
            if (param.Rows.Count > 0)
            {
                foreach (DataRow r in param.Rows)
                {
                    string _ApsPlanInfoIDs = r["apsPlanInfoIDs"].ToString();
                    foreach (string id in _ApsPlanInfoIDs.Split(','))
                    {
                        if (string.IsNullOrWhiteSpace(id))
                        {
                            continue;
                        }
                        para["ApsPlanInfoIDs"] += "'" + id + "',";
                    }

                }
            }
        }
        para["ApsPlanInfoIDs"] = para["ApsPlanInfoIDs"].TrimEnd(',');

        if (para.Keys.Count == 0)
        {
            result.Message = "参数无效";
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }

        DataTable dt = m_LMObj.GetStepLMAps(para);

        if (dt.Rows.Count == 0)
        {
            result.Message = "无数据";
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }

        Dictionary<string, object> apsData = new Dictionary<string, object>();
        List<Dictionary<string, object>> returnData = new List<Dictionary<string, object>>();

        DataTable conDt = dt.DefaultView.ToTable(true, "containerid", "workflowid");//批次 

        foreach (DataRow con in conDt.Rows)
        {
            var conStepApsInfo = dt.Select("containerid='" + con["containerid"].ToString() + "' and workflowid='" + con["workflowid"].ToString() + "'").CopyToDataTable();
            var conApsInfo = conStepApsInfo.DefaultView.ToTable(true, "apsplaninfoid", "constarttime", "conendtime", "containername", "ApsType", "containerid", "workflowid");//批次级计划
            var conApsRow = conApsInfo.Rows[0];

            apsData = new Dictionary<string, object>();
            apsData["id"] = conApsRow["containerid"].ToString();
            apsData["name"] = conApsRow["containername"].ToString();

            List<Dictionary<string, object>> conperiods = new List<Dictionary<string, object>>();
            Dictionary<string, object> conPeriod = new Dictionary<string, object>();
            Dictionary<string, object> customData = new Dictionary<string, object>();
            //批次级计划，可能3种方案
            foreach (DataRow _conApsRow in conApsInfo.Rows)
            {
                conPeriod = new Dictionary<string, object>();
                var apsType = ""; var fillColor = "";
                switch (_conApsRow["ApsType"].ToString())
                {
                    case "1":
                        apsType = "正排";
                        fillColor = "#64b5f6";
                        break;
                    case "2":
                        apsType = "倒排";
                        fillColor = "#009688";
                        break;
                    case "3":
                        apsType = "瓶颈排";
                        fillColor = "#9d8a0e";
                        break;
                    default:
                        break;
                }
                conPeriod["id"] = _conApsRow["apsplaninfoid"].ToString();
                conPeriod["text"] = _conApsRow["containername"].ToString() + "(" + apsType + ")";
                conPeriod["start"] = _conApsRow["constarttime"].ToString();
                conPeriod["end"] = _conApsRow["conendtime"].ToString();
                conPeriod["fill"] = fillColor;

                //个性化属性
                customData = new Dictionary<string, object>();
                customData["apsType"] = _conApsRow["ApsType"].ToString();

                conPeriod["customData"] = customData;

                conperiods.Add(conPeriod);
            }
            apsData["periods"] = conperiods;

            //批次级个性化属性
            customData = new Dictionary<string, object>();
            customData["containerid"] = con["containerid"].ToString();
            customData["workflowid"] = con["workflowid"].ToString();

            apsData["customData"] = customData;

            returnData.Add(apsData);

            //工序级信息
            DataTable conStep = conStepApsInfo.DefaultView.ToTable(true, "containerid", "workflowid", "workflowstepid", "workflowstepname");//工序信息                      

            foreach (DataRow step in conStep.Rows)
            {
                Dictionary<string, object> stepApsData = new Dictionary<string, object>();

                stepApsData["id"] = step["workflowstepid"].ToString();
                stepApsData["name"] = step["workflowstepname"].ToString();
                List<Dictionary<string, object>> periods = new List<Dictionary<string, object>>();
                Dictionary<string, object> period = new Dictionary<string, object>();

                //此批次和此工序的所有排产计划
                DataTable _conStepApsInfo = conStepApsInfo.Select("containerid='" + con["containerid"].ToString() + "' and workflowstepid='" + step["workflowstepid"].ToString() + "'").CopyToDataTable();
                foreach (DataRow stepAps in _conStepApsInfo.Rows)
                {
                    period = new Dictionary<string, object>();
                    var apsType = ""; var fillColor = "";
                    switch (stepAps["ApsType"].ToString())
                    {
                        case "1":
                            apsType = "正排";
                            fillColor = "#64b5f6";
                            break;
                        case "2":
                            apsType = "倒排";
                            fillColor = "#009688";
                            break;
                        case "3":
                            apsType = "瓶颈排";
                            fillColor = "#9d8a0e";
                            break;
                        default:
                            break;
                    }
                    period["id"] = stepAps["apsplandetailid"].ToString();
                    period["text"] = stepAps["workflowstepname"].ToString() + "(" + apsType + ")";
                    period["start"] = stepAps["stepstarttime"].ToString();
                    period["end"] = stepAps["stependtime"].ToString();
                    period["fill"] = fillColor;
                    //个性化属性
                    customData = new Dictionary<string, object>();
                    customData["apsType"] = stepAps["ApsType"].ToString();
                    if (stepAps["workflowstepid"].ToString() == stepAps["cciworkflowstepid"].ToString())
                    {
                        customData["isCurStep"] = "1";//当前序
                    }
                    period["customData"] = customData;

                    periods.Add(period);
                }



                //测试，添加假期
                //if (stepAps["workflowstepname"].ToString() == "50-工序50")
                //{
                //    period = new Dictionary<string, object>();
                //    period["id"] = Guid.NewGuid().ToString();
                //    period["text"] = "假期";
                //    period["start"] = "2022/4/30 0:00:00";
                //    period["end"] = "2022/5/4 0:00:00";
                //    period["customData"] = new Dictionary<string, string>() { { "isHolidate", "1" } };
                //    periods.Add(period);
                //}                

                stepApsData["periods"] = periods;
                stepApsData["parent"] = conApsRow["containerid"].ToString();

                returnData.Add(stepApsData);
            }

        }

        result.ReturnData = JsonConvert.SerializeObject(returnData);
        //result.DBTable = dt;
        result.Result = true;
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    /// <summary>
    /// 有限产能批次级数据查询
    /// </summary>
    /// <param name="context"></param>
    public void GetContainerLMAps(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        uMESProcessResult result = new uMESProcessResult();
        result.Result = false;

        Dictionary<string, string> para = new Dictionary<string, string>();
        para["EmployeeID"] = m_UserInfo.EmployeeID.ToString();

        DataTable conDt = new DataTable();
        if (!string.IsNullOrWhiteSpace(context.Request.Form["containers"].ToString()))
        {
            conDt = JsonConvert.DeserializeObject<DataTable>(context.Request.Form["containers"].ToString());
        }
        else
        {
            result.Message = "无效参数";
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }
        if (context.Request["apsType"] != null && !string.IsNullOrWhiteSpace(context.Request["apsType"].ToString()))
        {
            para["ApsType"] = context.Request["apsType"].ToString();
        }

        DataTable dt = m_LMObj.GetContainerLMAps(conDt, para);
        result.DBTable = dt;
        result.Result = true;
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    /// <summary>
    /// 有限产能排产
    /// </summary>
    /// <param name="context"></param>
    public void ApsLmCalculate(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        uMESProcessResult result = new uMESProcessResult();
        result.Result = false;

        string apsType = context.Request["apstype"].ToString();
        Dictionary<string, string> para = new Dictionary<string, string>();
        para["EmployeeID"] = m_UserInfo.EmployeeID.ToString();

        DataTable conDt = new DataTable();
        if (!string.IsNullOrWhiteSpace(context.Request.Form["containers"].ToString()))
        {
            conDt = JsonConvert.DeserializeObject<DataTable>(context.Request.Form["containers"].ToString());
        }
        else
        {
            result.Message = "无效参数";
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }

        //yuxj20230224增加是否为整个排产池标记
        if (context.Request["isWholePool"] != null && conDt.Columns.Contains("apspoolid"))
        {
            string WholePoolId = "";
            if (context.Request["isWholePool"].ToString() == "1")
            {
                //重新根据poolid查询需要处理的数据 
                WholePoolId = conDt.Rows[0]["apspoolid"].ToString();
                conDt = m_LMObj.GetApsPoolContainerInfo(new Dictionary<string, string>() { { "PoolID", WholePoolId } }).DBTable;
            }
        }

        DataTable faConDt = new DataTable();
        if (conDt.Select("ISSUBCON is null").Length > 0)
        {
            faConDt = conDt.Select("ISSUBCON is null").CopyToDataTable();//主卡            
        }
        DataTable sonConDt = new DataTable();
        if (conDt.Select("ISSUBCON='1'").Length > 0)
        {
            sonConDt = conDt.Select("ISSUBCON='1'").CopyToDataTable();//子卡
            faConDt.Merge(sonConDt);
        }


        //排产主卡
        if (apsType == "1")//有限，正排
        {
            result = m_LMObj.LMPositiveCalculate(faConDt, para);
        }
        else if (apsType == "2")//有限，倒排
        {
            result = m_LMObj.LMReverseCalculate(faConDt, para);
        }
        else if (apsType == "3")//有限，瓶颈排
        {
            result = m_LMObj.LMBottleneckCalculate(faConDt, para);
        }
        /*
        //排产子卡
        if (result.Result && sonConDt.Rows .Count >0)
        {
            //sonConDt = m_LMObj.GetSonContainerStartEndDate(sonConDt, apsType);
            //if (sonConDt.Select("STARTTIME is null").Length > 0)
            //{
            //    result.Result = false;
            //    result.Message = "未找到主卡的子工序的排产信息";
            //}
            //else {
                if (apsType == "1")//有限，正排
                {
                    result = m_LMObj.LMPositiveCalculate(sonConDt, para);
                }
                else if (apsType == "2")//有限，倒排
                {
                    result = m_LMObj.LMReverseCalculate(sonConDt, para);
                }
                else if (apsType == "3")//有限，瓶颈排
                {
                    result = m_LMObj.LMBottleneckCalculate(sonConDt, para); 
                }
            //}
            
        }
        */
        if (!result.Result)
        {
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }

        //重置参数，刷新数据
        para.Clear();
        para["EmployeeID"] = m_UserInfo.EmployeeID.ToString();
        DataTable dt = m_LMObj.GetContainerLMAps(conDt, para);//刷新排产数据

        result.Result = true;
        result.DBTable = dt;
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    /// <summary>
    /// 移除排产池
    /// </summary>
    /// <param name="context"></param>
    public void RemoveApsPool(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        uMESProcessResult result = new uMESProcessResult();
        result.Result = false;

        if (!string.IsNullOrWhiteSpace(context.Request["containers"].ToString()))
        {
            var containers = JsonConvert.DeserializeObject<DataTable>(context.Request["containers"].ToString());
            if (containers.Rows.Count == 0)
            {
                result.Message = "无参数";
                context.Response.Write(JsonConvert.SerializeObject(result));
                return;
            }

            m_LMObj.RemoveApsPool(containers);
        }
        else
        {
            result.Message = "无参数";
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }

        result.Result = true;
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    /// <summary>
    /// 计算排产池批次的优先级
    /// </summary>
    /// <param name="context"></param>
    public void calcContainerApsPriority(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        uMESProcessResult result = new uMESProcessResult();
        result.Result = false;

        if (!string.IsNullOrWhiteSpace(context.Request["containers"].ToString()))
        {
            var containers = JsonConvert.DeserializeObject<DataTable>(context.Request["containers"].ToString());
            if (containers.Rows.Count == 0)
            {
                result.Message = "无参数";
                context.Response.Write(JsonConvert.SerializeObject(result));
                return;
            }

            //yuxj20230224增加是否为整个排产池标记
            if (context.Request["isWholePool"] != null && containers.Columns.Contains("apspoolid"))
            {
                string WholePoolId = "";
                if (context.Request["isWholePool"].ToString() == "1")
                {
                    //重新根据poolid查询需要处理的数据 
                    WholePoolId = containers.Rows[0]["apspoolid"].ToString();
                    containers = m_LMObj.GetApsPoolContainerInfo(new Dictionary<string, string>() { { "PoolID", WholePoolId } }).DBTable;
                    //没有选择记录时，重新根据poolid查询赋值
                }
            }
            string msg = m_LMObj.calcContainerApsPriority(containers);
            if (msg != "")
            {
                result.Result = false;
                result.Message = msg;
                context.Response.Write(JsonConvert.SerializeObject(result));
                return;
            }
        }
        else
        {
            result.Message = "无参数";
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }

        result.Result = true;
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    /// <summary>
    /// 查询获取列表
    /// </summary>
    /// <param name="context"></param>
    public void SearchData(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        uMESProcessResult result = new uMESProcessResult();
        result.Result = false;

        Dictionary<string, string> para = SetPara(context);

        result = m_LMObj.GetApsPoolContainerInfo(para, true);
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    //设置字典列表
    private Dictionary<string, string> SetPara(HttpContext context)
    {
        Dictionary<string, string> para = new Dictionary<string, string>();

        para.Add("CurrentPageIndex", context.Request.Form["pageNumber"].ToString());//页码
        para.Add("PageSize", context.Request.Form["pageSize"].ToString());//每页页数


        if (!string.IsNullOrWhiteSpace(context.Request.Form["isPrepare"].ToString()))
        {
            para.Add("IsPrepare", context.Request.Form["isPrepare"].ToString());
        }
        if (!string.IsNullOrWhiteSpace(context.Request.Form["containerName"].ToString()))
        {
            para.Add("ContainerName", context.Request.Form["containerName"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(context.Request.Form["productName"].ToString()))
        {
            para.Add("ProductName", context.Request.Form["productName"].ToString());
        }

        if (context.Request.Form["isAps"].ToString() != "0")//不为全部时 查询已派或者未派
        {
            para.Add("IsAps", context.Request.Form["isAps"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(context.Request.Form["mfgorderName"].ToString()))
        {
            para.Add("MfgorderName", context.Request.Form["mfgorderName"].ToString());
        }
        //
        if (!string.IsNullOrWhiteSpace(context.Request.Form["factoryId"].ToString()))
        {
            para.Add("FactoryID", context.Request.Form["factoryId"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(context.Request.Form["poolId"].ToString()))//排产池
        {
            para.Add("PoolID", context.Request.Form["poolId"].ToString());
        }
        if (!string.IsNullOrWhiteSpace(context.Request.Form["orderBStartDate"].ToString()))
        {
            para.Add("OrderBStartDate", context.Request.Form["orderBStartDate"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(context.Request.Form["orderEStartDate"].ToString()))
        {
            para.Add("OrderEStartDate", context.Request.Form["orderEStartDate"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(context.Request.Form["orderBEndDate"].ToString()))
        {
            para.Add("OrderBEndDate", context.Request.Form["orderBEndDate"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(context.Request.Form["orderEEndDate"].ToString()))
        {
            para.Add("OrderEEndDate", context.Request.Form["orderEEndDate"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(context.Request.Form["realBStartDate2"].ToString()))
        {
            para.Add("RealBStartDate2", context.Request.Form["realBStartDate2"].ToString());
        }
        if (!string.IsNullOrWhiteSpace(context.Request.Form["realEStartDate2"].ToString()))
        {
            para.Add("RealEStartDate2", context.Request.Form["realEStartDate2"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(context.Request.Form["workflowStepName"].ToString()))
        {
            para.Add("WorkflowStepName", context.Request.Form["workflowStepName"].ToString());
        }
        if (m_UserInfo != null)
        {
            para.Add("EmployeeID", m_UserInfo.EmployeeID.ToString());
        }
        if (!string.IsNullOrWhiteSpace(context.Request.Form["workcenterid"].ToString()))
        {
            para.Add("workcenterid", context.Request.Form["workcenterid"].ToString());
        }
        if (!string.IsNullOrWhiteSpace(context.Request.Form["teamid"].ToString()))
        {
            para.Add("teamid", context.Request.Form["teamid"].ToString());
        }
        return para;
    }
    /// <summary>
    /// 移入批次到排产池
    /// </summary>
    /// <param name="context"></param>
    public void MoveConToApsPool(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        uMESProcessResult result = new uMESProcessResult();
        result.Result = false;

        if (!string.IsNullOrWhiteSpace(context.Request["containers"].ToString()))
        {
            var containers = JsonConvert.DeserializeObject<DataTable>(context.Request["containers"].ToString());
            if (containers.Rows.Count == 0)
            {
                result.Message = "无参数";
                context.Response.Write(JsonConvert.SerializeObject(result));
                return;
            }
            foreach (DataRow item in containers.Rows)
            {
                if (!string.IsNullOrWhiteSpace(item["expectmaterialdate"].ToString()))
                {
                    item["expectmaterialdate"] = DateTime.Parse(item["expectmaterialdate"].ToString()).ToString("yyyy-MM-dd");
                }
            }
            m_LMObj.MoveContainerToAps(containers);
        }
        else
        {
            result.Message = "无参数";
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }

        result.Result = true;
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    /// <summary>
    /// 获取有限排产需要选择的批次列表
    /// </summary>
    /// <param name="context"></param>
    public void GetApsSelectContainer(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        uMESProcessResult result = new uMESProcessResult();
        result.Result = false;

        Dictionary<string, string> para = new Dictionary<string, string>();

        para.Add("CurrentPageIndex", context.Request.Form["pageNumber"].ToString());//页码
        para.Add("PageSize", context.Request.Form["pageSize"].ToString());//每页页数

        if (!string.IsNullOrWhiteSpace(context.Request.Form["containerName"].ToString()))
        {
            para.Add("ContainerName", context.Request.Form["containerName"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(context.Request.Form["productName"].ToString()))
        {
            para.Add("ProductName", context.Request.Form["productName"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(context.Request.Form["mfgorderName"].ToString()))
        {
            para.Add("MfgorderName", context.Request.Form["mfgorderName"].ToString());
        }
        if (!string.IsNullOrWhiteSpace(context.Request.Form["factoryId"].ToString()))
        {
            para.Add("FactoryID", context.Request.Form["factoryId"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(context.Request.Form["orderStartDate"].ToString()))
        {
            para.Add("OrderStartDate", context.Request.Form["orderStartDate"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(context.Request.Form["orderEndDate"].ToString()))
        {
            para.Add("OrderEndDate", context.Request.Form["orderEndDate"].ToString());
            if (para.ContainsKey("OrderStartDate"))
            {
                if (DateTime.Parse(para["OrderStartDate"]) > DateTime.Parse(para["OrderEndDate"]))
                {
                    result.Result = false;
                    result.Message = "开始日期大于结束日期";
                    context.Response.Write(JsonConvert.SerializeObject(result));
                    return;
                }
            }
        }
        //para.Add("FactoryID", m_UserInfo.FactoryID);

        result = m_LMObj.GetApsSelectContainer(para);
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    /// <summary>
    /// 导出排产错误日志数据
    /// </summary>
    /// <param name="context"></param>
    public void ExportApsScheduledTaskLogs(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        uMESProcessResult result = new uMESProcessResult();
        result.Result = false;
        Dictionary<string, string> para = SetPara(context);
        DataTable dt = m_LMObj.ApsContainerSTLogExport(para);
        dt.Columns["MFGORDERNAME"].ColumnName = "订单号";
        dt.Columns["CONTAINERNAME"].ColumnName = "批次";
        dt.Columns["PRODUCTDESC"].ColumnName = "零件名称";
        dt.Columns["QTY"].ColumnName = "在制数";
        dt.Columns["ISPREPARE"].ColumnName = "齐套";
        dt.Columns["STEPDURATION"].ColumnName = "批次总期量";
        dt.Columns["CRITICALVALUE"].ColumnName = "批次临界比";
        dt.Columns["APSSEQUENCE"].ColumnName = "排产顺序号";
        dt.Columns["WORKFLOWINFO"].ColumnName = "工艺信息";
        dt.Columns["WORKFLOWSTEPNAME"].ColumnName = "当前工序";
        dt.Columns["CONTAINERTYPENAME"].ColumnName = "流水卡类型";
        dt.Columns["REALSTARTDATE"].ColumnName = "实际开始日期";
        dt.Columns["EXPECTMATERIALDATE"].ColumnName = "手动指定开始";
        dt.Columns["MFGSTARTDATE"].ColumnName = "订单开始日期";
        dt.Columns["MFGENDDDATE"].ColumnName = "订单结束日期";
        dt.Columns["ISSUBCON"].ColumnName = "主子卡";
        dt.Columns["LOGMESSAGE"].ColumnName = "排产日志";


        var ms = uLMS_CommonFunction.DataTableExportToExcel(dt, "有限排产错误日志");
        if (ms != null)
        {
            var Response = HttpContext.Current.Response;
            Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}{1}.xls", HttpContext.Current.Server.UrlEncode("有限排产错误日志"), DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss")));
            Response.AddHeader("fileDownload", "1");
            Response.AddHeader("Set-Cookie", "fileDownload=true;path=/");
            Response.ContentEncoding = System.Text.Encoding.GetEncoding("UTF-8");
            Response.ContentType = "application/ms-excel;charset=UTF-8";
            Response.BinaryWrite(ms);
            Response.Flush();
            Response.End();
            Response.Close();
            result.Result = true;
            context.Response.Write(JsonConvert.SerializeObject(Response));
        }
        else
        {
            result.Message = "无数据";
            context.Response.AddHeader("fileDownload", "0");
            context.Response.Write(JsonConvert.SerializeObject(result));
        }



    }

}